package heap

import "gvm/classfile"

type FieldRef struct {
	MemberRef
	field *Field
}

func NewFieldRef(cp *ConstantPool, fieldRef *classfile.Constant_Field_Ref) *FieldRef {
	ref := &FieldRef{}
	ref.constantPool = cp
	ref.copyFiled(fieldRef)
	return ref
}

func (self *FieldRef) ResolveField() *Field {
	if self.field == nil {
		self.resolveField()
	}
	return self.field
}

func (self *FieldRef) resolveField() {
	cf := self.constantPool.class
	kc := self.ResolveClass()
	field := lookupField(kc, self.name, self.descriptor)
	if field == nil {
		panic("java.lang.NoSuchFileError")
	}
	if !field.isAccessibleTo(cf) {
		panic("java.lang.IllegalAccessError")
	}
	self.field = field
}

func (self *FieldRef) ResolvedField() *Field {
	return self.ResolveField()
}

func lookupField(c *Klass, name string, descriptor string) *Field {
	for _, field := range c.fields {
		if field.name == name && field.descriptor == descriptor {
			return field
		}
	}
	for _, iface := range c.interfaces {
		if field := lookupField(iface, name, descriptor); field != nil {
			return field
		}
	}
	if c.superClass != nil {
		return lookupField(c.superClass, name, descriptor)
	}
	return nil
}
